package com.persistencia;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.entidades.xml.BaseObject;
import com.exceptions.PersistenceException;
import com.persistencia.util.RecordStrategy;
import com.persistencia.util.RecordXml;


/**
 * The Class XMLPersistence.
 * 
 * @param <T>
 *            the generic type
 */
public class XMLPersistence<T> implements Persistence<T> {

	
	private  RecordStrategy recordData;
	// concurrent hash map is synchronized
	private final Map<String, T> dataMap = new ConcurrentHashMap<String, T>();

	public XMLPersistence(Class<T> T) {
		super();
		try {
			
			// define which will be the persistence type
			recordData = new RecordXml(T);
		
			loadFromFile();
		} catch (PersistenceException e) {
			e.toString();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.montran.financial.persistence.Persistence#create(java.lang.Object)
	 */
	@Override
	public Boolean create(T entidad) {
		// TODO revisar por que no remplaza si ya existe
		/*if ((entidad == null) || entidad.trim().equals("")) {
            throw new IllegalArgumentException("memberName should not be null or empty.");
        }*/
		BaseObject base = (BaseObject) entidad;
		if (findById(base.getId()) == null) {
			dataMap.put(base.getId(), entidad);
			return true;
		}
		return false;
	}

	/*
	 * (non-Javadoc) get all the data from the file
	 * 
	 * @see com.montran.financial.persistence.Persistence#getAll()
	 */
	@Override
	public List<T> findAll() {
		List<T> list = new ArrayList<T>(
				(Collection<? extends T>) dataMap.values());
		return list;
	}

	@Override
	public T findById(String id) {
		return dataMap.get(id);
	}

	@Override
	public Boolean update(T entidad) {
		// TODO revisar por que no remplaza si ya existe
		BaseObject base = (BaseObject) entidad;
		if (findById(base.getId()) != null) {
			dataMap.put(base.getId(), entidad);
			return true;
		}
		return false;
	}

	@Override
	public Boolean delete(String id) {
		Object obj = dataMap.remove(id);
		if (obj == null) {
			return false;
		}
		return true;
	}

	public final void commitToFile() {
		try {
			recordData.writeData(findAll());
			
		} catch (PersistenceException e) {
			e.toString();
		}
	}

	@SuppressWarnings("unchecked")
	public final void loadFromFile() {
		try {
			dataMap.clear();
			for (Object obj : recordData.readData()) {

				T t = (T) obj;

				BaseObject base = (BaseObject) obj;
				dataMap.put(base.getId(), t);
			}
		} catch (PersistenceException e) {
			e.toString();
		}
	}
}
